const mongoose = require('../infrastructure/Mongoose')
const { Schema } = mongoose
const { ObjectId } = Schema

const MIN_NAME_LENGTH = 3
const MAX_NAME_LENGTH = 200
const MIN_VARIANT_NAME_LENGTH = 3
const MAX_VARIANT_NAME_LENGTH = 255
const NAME_REGEX = /^[a-z0-9-]+$/

const RolloutPercentType = {
  type: Number,
  default: 0,
  min: [0, 'Rollout percentage must be between 0 and 100, got {VALUE}'],
  max: [100, 'Rollout percentage must be between 0 and 100, got {VALUE}'],
  required: true,
}

const BadgeSchema = new Schema(
  {
    tooltipText: {
      type: String,
      required: false,
    },
    url: {
      type: String,
      required: false,
    },
  },
  { _id: false }
)

const BadgeInfoSchema = new Schema(
  {
    alpha: BadgeSchema,
    beta: BadgeSchema,
    release: BadgeSchema,
  },
  { _id: false }
)

const VariantSchema = new Schema(
  {
    name: {
      type: String,
      minLength: MIN_VARIANT_NAME_LENGTH,
      maxLength: MAX_VARIANT_NAME_LENGTH,
      required: true,
      validate: {
        validator: function (input) {
          return input !== null && input !== 'default' && NAME_REGEX.test(input)
        },
        message: `invalid, cannot be 'default' and must match: ${NAME_REGEX}, got {VALUE}`,
      },
    },
    rolloutPercent: RolloutPercentType,
    rolloutStripes: [
      {
        start: RolloutPercentType,
        end: RolloutPercentType,
      },
    ],
  },
  { _id: false }
)

const VersionSchema = new Schema(
  {
    versionNumber: {
      type: Number,
      default: 1,
      min: [1, 'must be 1 or higher, got {VALUE}'],
      required: true,
    },
    phase: {
      type: String,
      default: 'alpha',
      enum: ['alpha', 'beta', 'release'],
      required: true,
    },
    active: {
      type: Boolean,
      default: true,
      required: true,
    },
    analyticsEnabled: {
      type: Boolean,
      default: true,
      required: true,
    },
    variants: [VariantSchema],
    createdAt: {
      type: Date,
      default: Date.now,
    },
    author: { type: ObjectId, ref: 'User' },
    comment: {
      type: String,
      required: false,
    },
  },
  { _id: false }
)

const SplitTestSchema = new Schema(
  {
    name: {
      type: String,
      minLength: MIN_NAME_LENGTH,
      maxlength: MAX_NAME_LENGTH,
      required: true,
      unique: true,
      validate: {
        validator: function (input) {
          return input !== null && NAME_REGEX.test(input)
        },
        message: `invalid, must match: ${NAME_REGEX}`,
      },
    },
    versions: [VersionSchema],
    forbidReleasePhase: {
      type: Boolean,
      required: false,
    },
    description: {
      type: String,
      required: false,
    },
    expectedEndDate: {
      type: Date,
      required: false,
    },
    ticketUrl: {
      type: String,
      required: false,
    },
    reportsUrls: {
      type: [String],
      required: false,
      default: [],
    },
    winningVariant: {
      type: String,
      required: false,
    },
    archived: {
      type: Boolean,
      required: false,
    },
    archivedAt: {
      type: Date,
      required: false,
    },
    archivedBy: { type: ObjectId, ref: 'User' },
    badgeInfo: {
      type: BadgeInfoSchema,
      required: false,
    },
  },
  { minimize: false }
)

module.exports = {
  SplitTest: mongoose.model('SplitTest', SplitTestSchema),
  SplitTestSchema,
}
